﻿using System;
using System.Collections.Generic;
using System.Globalization;
using Monkey.Warrenty.Bo;
using Monkey.Warrenty.Data;
using Monkey.Warrenty.Data.Interfaces;
using Monkey.Warrenty.EntityModel;
using Monkey.Warrenty.Enum;
using MonkeyWarranty.Models.WarrantyModels;

namespace Monkey.Warrenty.Biz
{
    public class WarrantyTicketBiz
    {
        #region Properties

        private const string DateFormat = "dd/MM/yyyy";

        private readonly IWarrantyTicketDao _warrantyTicketDao;
        private readonly IEmployeeDao _employeeDao;
        private readonly IDealerDao _dealerDao;
        private readonly ICustomerDao _customerDao;
        private readonly IWarrantyTicketStatusDao _warrantyTicketStatusDao;
        private readonly IWarrantyProductStatusDao _warrantyProductStatusDao;

        #endregion

        #region Constructors

        public WarrantyTicketBiz()
        {
            _warrantyTicketDao = new WarrantyTicketDao();
            _employeeDao = new EmployeeDao();
            _dealerDao = new DealerDao();
            _customerDao = new CustomerDao();
            _warrantyTicketStatusDao = new WarrantyTicketStatusDao();
            _warrantyProductStatusDao = new WarrantyProductStatusDao();
        }

        #endregion

        #region Select Methods

        public long GetNextCode()
        {
            return _warrantyTicketDao.GetCurrentIdentity() + 1;
        }

        public List<Employee> GetEmployees()
        {
            return _employeeDao.GetAllEmployees();
        }

        public List<Dealer> GetDealers()
        {
            return _dealerDao.GetDealers();
        }

        public List<WarrantyTicketView> GetTickets(int jtStartIndex, int jtPageSize, string jtSorting, int status)
        {
            return _warrantyTicketDao.GetTicketViews(jtStartIndex, jtPageSize, jtSorting, status);
        }

        public int GetTicketCount(int jtStartIndex, int jtPageSize, string jtSorting, int status)
        {
            return _warrantyTicketDao.GetTicketCountByFilter(status);
        }

        public List<WarrantyTicketView> GetActiveTickets(int jtStartIndex, int jtPageSize, string jtSorting)
        {
            return _warrantyTicketDao.GetActiveTicketViews(jtStartIndex, jtPageSize, jtSorting);
        }

        public int GetActiveTicketCount(int jtStartIndex, int jtPageSize, string jtSorting)
        {
            return _warrantyTicketDao.GetActiveTicketCount();
        }

        public object GetTicketsWs(int jtStartIndex, int jtPageSize, string jtSorting, int status)
        {
            var ticketCount = _warrantyTicketDao.GetTicketCountByFilter(status);
            var warrantyTicketViews = _warrantyTicketDao.GetTicketViews(jtStartIndex, jtPageSize, jtSorting, status);

            foreach (var warrantyTicketView in warrantyTicketViews)
            {
                warrantyTicketView.CreatedTimeString = string.Format("{0:HH:mm}", warrantyTicketView.CreatedDate);
            }

            return new { Result = "OK", Records = warrantyTicketViews, TotalRecordCount = ticketCount };
        }

        public WarrantyTicket GetById(long id)
        {
            return id <= 0 ? null : _warrantyTicketDao.GetById(id);
        }

        public int SearchTicketsCount(WarrantySearchModel searchModel)
        {
            DateTime createdDateFrom, createdDateTo, deliveryDateFrom, deliveryDateTo;
            if (!string.IsNullOrEmpty(searchModel.CreatedDateFromString) &&
                DateTime.TryParseExact(searchModel.CreatedDateFromString, DateFormat, CultureInfo.InvariantCulture,
                DateTimeStyles.None, out createdDateFrom))
            {
                searchModel.CreatedDateFrom = createdDateFrom;
            }
            if (!string.IsNullOrEmpty(searchModel.CreatedDateToString) &&
                DateTime.TryParseExact(searchModel.CreatedDateToString, DateFormat, CultureInfo.InvariantCulture,
                DateTimeStyles.None, out createdDateTo))
            {
                searchModel.CreatedDateTo = createdDateTo;
            }
            if (!string.IsNullOrEmpty(searchModel.DeliveryDateFromString) &&
                DateTime.TryParseExact(searchModel.DeliveryDateFromString, DateFormat, CultureInfo.InvariantCulture,
                DateTimeStyles.None, out deliveryDateFrom))
            {
                searchModel.DeliveryDateFrom = deliveryDateFrom;
            }
            if (!string.IsNullOrEmpty(searchModel.DeliveryDateToString) &&
                DateTime.TryParseExact(searchModel.DeliveryDateToString, DateFormat, CultureInfo.InvariantCulture,
                DateTimeStyles.None, out deliveryDateTo))
            {
                searchModel.DeliveryDateTo = deliveryDateTo;
            }

            return _warrantyTicketDao.SearchTicketsCount(searchModel);
        }

        public List<WarrantyTicketView> SearchTickets(WarrantySearchModel searchModel)
        {
            DateTime createdDateFrom, createdDateTo, deliveryDateFrom, deliveryDateTo;
            if (!string.IsNullOrEmpty(searchModel.CreatedDateFromString) &&
                DateTime.TryParseExact(searchModel.CreatedDateFromString, DateFormat, CultureInfo.InvariantCulture,
                DateTimeStyles.None, out createdDateFrom))
            {
                searchModel.CreatedDateFrom = createdDateFrom;
            }
            if (!string.IsNullOrEmpty(searchModel.CreatedDateToString) && 
                DateTime.TryParseExact(searchModel.CreatedDateToString, DateFormat, CultureInfo.InvariantCulture,
                DateTimeStyles.None, out createdDateTo))
            {
                searchModel.CreatedDateTo = createdDateTo;
            }
            if (!string.IsNullOrEmpty(searchModel.DeliveryDateFromString) &&
                DateTime.TryParseExact(searchModel.DeliveryDateFromString, DateFormat, CultureInfo.InvariantCulture,
                DateTimeStyles.None, out deliveryDateFrom))
            {
                searchModel.DeliveryDateFrom = deliveryDateFrom;
            }
            if (!string.IsNullOrEmpty(searchModel.DeliveryDateToString) &&
                DateTime.TryParseExact(searchModel.DeliveryDateToString, DateFormat, CultureInfo.InvariantCulture,
                DateTimeStyles.None, out deliveryDateTo))
            {
                searchModel.DeliveryDateTo = deliveryDateTo;
            }

            return _warrantyTicketDao.SearchTickets(searchModel);
        } 

        #endregion

        #region CRUD

        public WarrantyTicket CreateTicket(WarrantyTicket ticket, Customer customer)
        {
            // check new or existed customer
            if (customer.Id == 0)
            {
                var maxCustomerId = _customerDao.GetMaxId();
                customer.Code = string.Format("{0:00000}", maxCustomerId + 1);
                customer = _customerDao.AddCustomer(customer);
            }

            // create warranty ticket
            ticket.CustomerId = customer.Id;
            _warrantyTicketDao.AddTicket(ticket);

            // send mail notification
            // var t = new Thread(() => EmailServiceFactory.GetEmailService().SendMail(EmailSettings.EmailFrom, ));

            return ticket;
        }

        public void UpdateTicket(WarrantyTicket ticket)
        {
            if (ticket == null || ticket.Id <= 0)
                return;

            _warrantyTicketDao.UpdateTicket(ticket);
        }

        public void DeleteTicket(long id)
        {
            if (id <= 0) throw new ApplicationException("InvalidTicket");

            _warrantyTicketDao.DeleteTicket(id);
        }

        #endregion

        #region Ticket Products

        public List<WarrantyTicketProductView> GetTicketProducts(long ticketId)
        {
            return ticketId <= 0 ? null : _warrantyTicketDao.GetTicketProducts(ticketId);
        }

        public void DeleteTicketProduct(long ticketProductId)
        {
            if (ticketProductId <= 0) return;
            _warrantyTicketDao.DeleteTicketProduct(ticketProductId);
        }

        public WarrantyTicket_Product CreateTicketProduct(WarrantyTicket_Product ticketProduct)
        {
            if (ticketProduct == null || ticketProduct.ProductId <= 0) return null;
            ticketProduct.WarrantyProductStatusId = 1; // WaitingWarranty

            ticketProduct.CreatedDate = DateTime.Now;

            // Create product
            _warrantyTicketDao.CreateTicketProduct(ticketProduct);

            // update ticket status to Processing
            _warrantyTicketDao.UpdateTicketStatus(ticketProduct.WarrantyTicketId, (int)WarrantyTicketStatus.Processing);

            return null;
        }

        public WarrantyTicket_Product GetTicketProductById(long id)
        {
            return id <= 0 ? null : _warrantyTicketDao.GetTicketProductById(id);
        }

        public void UpdateTicketProduct(WarrantyTicket_Product ticketProduct)
        {
            if (ticketProduct == null) return;

            _warrantyTicketDao.UpdateTicketProduct(ticketProduct);
        }

        #endregion

        #region Lend Products

        public List<WarrantyTicketLendProductView> GetTicketLendProducts(long ticketId)
        {
            return ticketId <= 0 ? null : _warrantyTicketDao.GetTicketLendProducts(ticketId);
        }

        public void DeleteTicketLendProduct(long ticketProductId)
        {
            if (ticketProductId <= 0) return;
            _warrantyTicketDao.DeleteTicketLendProduct(ticketProductId);
        }

        public WarrantyTicket_Product CreateTicketLendProduct(WarrantyTicket_LendProduct ticketProduct)
        {
            if (ticketProduct == null || ticketProduct.ProductId <= 0 || ticketProduct.EmployeeId <= 0) return null;

            ticketProduct.LendProductStatusId = LendProductStatus.Lending.GetHashCode();

            _warrantyTicketDao.CreateTicketLendProduct(ticketProduct);

            return null;
        }

        public WarrantyTicket_LendProduct GetTicketLendProductById(long id)
        {
            return id <= 0 ? null : _warrantyTicketDao.GetTicketLendProductById(id);
        }

        public void UpdateTicketLendProduct(WarrantyTicket_LendProduct ticketProduct)
        {
            if (ticketProduct == null) return;

            _warrantyTicketDao.UpdateTicketLendProduct(ticketProduct);
        }

        #endregion

        #region For printing

        public List<WarrantyTicketPrintBo> GetWarrantyTicketForPrint(long id)
        {
            if (id <= 0) return null;

            var tickets = new List<WarrantyTicketPrintBo>
                              {
                                  _warrantyTicketDao.GetWarrantyTicketForPrint(id)
                              };
            return tickets;
        }

        public List<TaskServiceBo> GetWarrantyTicketProductsForPrint(long id)
        {
            return id <= 0 ? null : _warrantyTicketDao.GetWarrantyTicketProductsForPrint(id);
        }

        public List<TaskServiceBo> GetWarrantyTicketLendProductsForPrint(long id)
        {
            return id <= 0 ? null : _warrantyTicketDao.GetWarrantyTicketLendProductsForPrint(id);
        }

        #endregion

        #region Ticket States

        public List<WarrantyTicketState> GetTicketStates()
        {
            return _warrantyTicketStatusDao.GetAllTicketStates();
        }

        #endregion

        #region warrenty product states

        public List<WarrantyProductState> GetWarrantyProductStates()
        {
            return _warrantyProductStatusDao.GetAll();
        }

        #endregion
    }
}
